MOB-52691: prototype remote Streamable HTTP transport (spike) - #35
Draft
dylan-white-bc wants to merge 1 commit into
Draft
MOB-52691: prototype remote Streamable HTTP transport (spike)#35dylan-white-bc wants to merge 1 commit into
dylan-white-bc wants to merge 1 commit into
Conversation
Adds an opt-in Streamable HTTP transport so the API Monitoring MCP server can run as a remote endpoint, while leaving local stdio behavior unchanged. Transport: - `--mcp http` or BZM_API_TEST_MCP_TRANSPORT=http selects Streamable HTTP; stdio remains the default. - Endpoint served at /mcp (configurable), with /health and /healthz probes for load-balancer checks. - stateless_http=True: the tools hold no cross-request state, so no MCP session store is needed and restarts do not invalidate clients. Authentication: - Hosted mode resolves the API Monitoring token per request from the Authorization header; it never falls back to a server-wide token. - stdio mode continues to use its startup token. - HTTP requests without a well-formed Bearer credential are rejected with 401 before any tool executes. - Requests carrying an Origin header are rejected (browser/CORS support is intentionally out of scope for this prototype). Note: this is pass-through auth -- the caller's token is forwarded to the API Monitoring APIs. The MCP specification treats this as an anti-pattern, so separate MCP authentication remains an open question for the epic. Tests: 150 passing, including request-scoped credential isolation and a regression test asserting the outgoing Authorization header carries the raw credential (BzmApimToken.__repr__ masks itself, so a non-string token would silently send a masked header).
There was a problem hiding this comment.
Pull request overview
Adds an opt-in Streamable HTTP transport path to run this MCP server as a remote HTTP endpoint, while keeping the default local stdio transport. This introduces request-scoped token resolution for hosted mode plus a basic HTTP security boundary (no browser Origin, Bearer required except health checks).
Changes:
- Add transport selection (
stdiodefault, opt-inhttp) and server construction logic, with Streamable HTTP hosted serving via Uvicorn. - Introduce hosted-mode auth/security primitives (
TokenResolver,HttpSecurityMiddleware,/health+/healthz) and update tool registration to use request-scoped tokens. - Add tests covering transport resolution, hosted-vs-stdio credential behavior, and HTTP middleware behavior; document Streamable HTTP hosting in the README.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_main_transport.py | Adds unit tests for CLI/env transport resolution and correct server startup behavior per transport. |
| tests/test_http_security.py | Adds tests for HTTP middleware behavior (Bearer required, Origin rejected, health unauthenticated). |
| tests/test_auth.py | Adds tests for request-scoped vs startup token resolution and that the resolved credential reaches API calls. |
| src/tools/test_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/team_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/step_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/schedule_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/result_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/environment_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/tools/bucket_manager.py | Switches tool registration to resolve token per request via TokenResolver. |
| src/server.py | Threads hosted-mode flag through tool registration and centralizes token resolution via TokenResolver. |
| src/config/auth.py | Adds request token parsing, token resolver, HTTP security middleware, health routes, and Streamable HTTP runner. |
| README.md | Documents how to run and configure the Streamable HTTP hosted endpoint and its auth/security expectations. |
| main.py | Adds transport selection/CLI changes, builds server for stdio vs HTTP, and runs Streamable HTTP when selected. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| host=host, | ||
| port=port, | ||
| streamable_http_path=os.getenv("FASTMCP_STREAMABLE_HTTP_PATH", "/mcp").strip() or "/mcp", | ||
| stateless_http=True, |
Comment on lines
+1
to
+6
| import anyio | ||
| import uvicorn | ||
| from mcp.server.fastmcp import Context, FastMCP | ||
| from starlette.requests import Request | ||
| from starlette.responses import JSONResponse | ||
| from starlette.types import ASGIApp, Receive, Scope, Send |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in Streamable HTTP transport so the API Monitoring MCP server can run as a
remote endpoint, while leaving local stdio behavior unchanged.
Epic: MOB-52691 — [API-MCP] Cloud-hosted API Monitoring MCP server (Streamable HTTP)
Spike: MOB-53088 — Spike: Support for Remote Http MCP server
Transport
--mcp httporBZM_API_TEST_MCP_TRANSPORT=httpselects Streamable HTTP; stdio remains the default./mcp(configurable viaFASTMCP_STREAMABLE_HTTP_PATH), with/healthand/healthzprobes for load-balancer checks.stateless_http=True— the tools hold no cross-request state, so no MCP session store is needed and restarts do not invalidate clients.Authentication
Authorizationheader; it never falls back to a server-wide token.401before any tool executes.Originheader are rejected — browser/CORS support is intentionally out of scope for this prototype.Note
This is pass-through auth — the caller's token is forwarded to the API Monitoring APIs.
The MCP specification treats this as an anti-pattern,
so separate MCP authentication remains an open question for MOB-52691.